package com.huahua.api.controller.utility;

import com.huahua.api.entity.base.R;
import com.huahua.api.entity.param.clipboard.*;
import com.huahua.api.entity.vo.clipboard.RandomPasswordVO;
import com.huahua.api.entity.vo.clipboard.WebClipboardVO;
import com.huahua.api.exception.CommonException;
import com.huahua.api.service.WebClipboardService;
import com.huahua.api.util.CheckUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

/**
 * @author Huahua-Ai
 * @date 2025-01-21 22:35:00
 * @description 网络剪贴板控制器
 */
@RestController
@RequestMapping("/api/utility/clipboard")
@RequiredArgsConstructor
@Slf4j
public class WebClipboardController {

    private final WebClipboardService webClipboardService;

    /**
     * 创建剪贴板
     */
    @PostMapping("/create")
    public Mono<R<WebClipboardVO>> createClipboard(@RequestBody CreateClipboardParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::createClipboard)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("创建剪贴板失败: {}", e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 获取剪贴板内容
     */
    @PostMapping("/get")
    public Mono<R<WebClipboardVO>> getClipboard(@RequestBody GetClipboardParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::getClipboard)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("获取剪贴板失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 更新剪贴板内容
     */
    @PutMapping("/update")
    public Mono<R<WebClipboardVO>> updateClipboard(@RequestBody UpdateClipboardParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("更新参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::updateClipboard)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("更新剪贴板失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 修改访问密码
     */
    @PutMapping("/change-access-password")
    public Mono<R<Boolean>> changeAccessPassword(@RequestBody ChangeAccessPasswordParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::changeAccessPassword)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("修改访问密码失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 修改管理员密码
     */
    @PutMapping("/change-admin-password")
    public Mono<R<Boolean>> changeAdminPassword(@RequestBody ChangeAdminPasswordParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::changeAdminPassword)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("修改管理员密码失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 生成随机访问密码
     */
    @PutMapping("/generate-access-password")
    public Mono<R<RandomPasswordVO>> generateAccessPassword(@RequestBody GenerateRandomAccessPasswordParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::generateRandomAccessPassword)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("生成随机访问密码失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 生成随机管理员密码
     */
    @PutMapping("/generate-admin-password")
    public Mono<R<RandomPasswordVO>> generateAdminPassword(@RequestBody GenerateRandomAdminPasswordParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::generateRandomAdminPassword)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("生成随机管理员密码失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 设置编辑权限
     */
    @PutMapping("/set-editable")
    public Mono<R<WebClipboardVO>> setEditable(@RequestBody SetEditableParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::setEditable)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("设置编辑权限失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 设置剪贴板过期时间
     */
    @PutMapping("/set-expire")
    public Mono<R<WebClipboardVO>> setExpireTime(@RequestBody ExtendExpireParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    CheckUtil.checkNotNull(param.getExpireTime(), new CommonException("过期时间不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::setExpireTime)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("设置过期时间失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 删除剪贴板
     */
    @DeleteMapping("/delete")
    public Mono<R<Boolean>> deleteClipboard(@RequestBody DeleteClipboardParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::deleteClipboard)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("删除剪贴板失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

    /**
     * 检查是否允许无密码访问
     */
    @PostMapping("/check-password-free")
    public Mono<R<Boolean>> checkPasswordFreeAccess(@RequestBody CheckPasswordFreeAccessParam param) {
        return Mono.fromCallable(() -> {
                    CheckUtil.checkNotNull(param, new CommonException("请求参数不能为空"));
                    CheckUtil.checkStrNotBlank(param.getShareId(), new CommonException("分享ID不能为空"));
                    return param;
                })
                .flatMap(webClipboardService::checkPasswordFreeAccess)
                .map(R::success)
                .onErrorResume(e -> {
                    log.error("检查无密码访问失败: shareId={}, error={}", param.getShareId(), e.getMessage());
                    return Mono.just(R.error(e.getMessage()));
                });
    }

}